package cn.cqautotest.cqviehelper.views;

import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import androidx.annotation.IdRes;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.ToastUtils;

import cn.cqautotest.cqviehelper.R;
import cn.cqautotest.cqviehelper.adapters.ItemRvClassDetailAdapter;
import cn.cqautotest.cqviehelper.beans.WeekNumbers;
import cn.cqautotest.cqviehelper.utils.MyScheduleSupport;

import com.zhuangfei.timetable.model.Schedule;

import java.util.ArrayList;
import java.util.List;

public class ClassDetailPopWindow extends PopupWindow {

    private static final String TAG = "ClassDetailPopWindow";
    private final Context mContext;
    private final View mPopView;
    private EditText mEtCourseName;
    private EditText mEtRoomName;
    private EditText mEtTeacherName;
    private TextView mTvClassTime;
    private RadioGroup mRgWeekSelector;
    private RadioButton mRbSingleWeek;
    private RadioButton mRbDoubleWeek;
    private RadioButton mRbSelectAll;
    private RecyclerView mRvWeekList;
    private TextView mBtnCancel;
    private TextView mBtnSubmit;
    private GridLayoutManager mLayoutManager;
    private ItemRvClassDetailAdapter mClassDetailAdapter;
    private ArrayList<Integer> mWeekList = new ArrayList<>();
    private ArrayList<WeekNumbers> mWeekNumbers = new ArrayList<>();
    private Schedule mSchedule = new Schedule();
    public static final int DEFAULT_MAX_WEEK = 20;
    private int maxWeek = DEFAULT_MAX_WEEK;
    private Window mWindow;
    private ValueAnimator mEnterBgAnimator;
    private ValueAnimator mOutBgAnimator;
    private CheckBox mCourseEditBtn;
    private InputNumberView mInputNumberView;

    public ClassDetailPopWindow(Context context, Window window) {
        super(ViewGroup.LayoutParams.MATCH_PARENT, ConvertUtils.dp2px(650));
        mContext = context;
        mWindow = window;
        //如果不获取焦点，则输入法无法弹出
        setFocusable(true);
        //默认点击窗体外部无法取消显示PopWindow
        setOutsideTouchable(true);
        //设置背景为透明
        setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        mPopView = LayoutInflater.from(mContext).inflate(R.layout.pop_class_detail, null);
        setContentView(mPopView);
        setAnimationStyle(R.style.pop_animation);
        initView();
        initEvent();
        initBgAnimation();
    }

    private void initView() {
        mCourseEditBtn = mPopView.findViewById(R.id.courseEditBtn);
        mEtCourseName = mPopView.findViewById(R.id.etCourseName);
        mEtRoomName = mPopView.findViewById(R.id.etRoomName);
        mEtTeacherName = mPopView.findViewById(R.id.etTeacherName);
        mTvClassTime = mPopView.findViewById(R.id.tvClassTime);
        mInputNumberView = mPopView.findViewById(R.id.inputNumberView);
        mRgWeekSelector = mPopView.findViewById(R.id.rgWeekSelector);
        mRbSingleWeek = mPopView.findViewById(R.id.rbSingleWeek);
        mRbDoubleWeek = mPopView.findViewById(R.id.rbDoubleWeek);
        mRbSelectAll = mPopView.findViewById(R.id.rbSelectAll);
        mRvWeekList = mPopView.findViewById(R.id.rvWeekList);
        mBtnCancel = mPopView.findViewById(R.id.btnCancel);
        mBtnSubmit = mPopView.findViewById(R.id.btnSubmit);
        mLayoutManager = new GridLayoutManager(mContext, 5);
        mClassDetailAdapter = new ItemRvClassDetailAdapter(mContext);
        mRvWeekList.setLayoutManager(mLayoutManager);
        mRvWeekList.setAdapter(mClassDetailAdapter);
        for (int i = 0; i < maxWeek; i++) {
            mWeekNumbers.add(new WeekNumbers(i + 1));
        }
        mRbSelectAll.setChecked(true);
        notifyAdapterDataChanged();
    }

    public View findViewById(@IdRes int id) {
        return mPopView.findViewById(id);
    }

    /**
     * 初始化背景动画
     */
    private void initBgAnimation() {
        int BG_ANIMATION_DURATION = 800;
        mEnterBgAnimator = ValueAnimator.ofFloat(1.0f, 0.7f);
        mEnterBgAnimator.setDuration(BG_ANIMATION_DURATION);
        mEnterBgAnimator.addUpdateListener(animation -> {
            float value = (float) animation.getAnimatedValue();
            //处理一下背景，有点透明度
            updateBgAlpha(value);
        });
        //退出的
        mOutBgAnimator = ValueAnimator.ofFloat(0.7f, 1.0f);
        mOutBgAnimator.setDuration(BG_ANIMATION_DURATION);
        mOutBgAnimator.addUpdateListener(animation -> {
            float value = (float) animation.getAnimatedValue();
            updateBgAlpha(value);
        });
    }

    public ClassDetailPopWindow startEnterAnim() {
        mEnterBgAnimator.start();
        return this;
    }

    public ClassDetailPopWindow startOutAnim() {
        mOutBgAnimator.start();
        return this;
    }

    /**
     * 在弹出popWindow的时候改变窗体的透明度
     *
     * @param alpha 透明度
     */
    private void updateBgAlpha(float alpha) {
        if (mWindow == null) return;
        WindowManager.LayoutParams attributes = mWindow.getAttributes();
        attributes.alpha = alpha;
        mWindow.setAttributes(attributes);
    }

    private void notifyAdapterDataChanged() {
        mClassDetailAdapter.setObjects(mWeekNumbers);
    }

    public ClassDetailPopWindow resetSchedule() {
        Schedule schedule = new Schedule();
        List<Integer> weekList = new ArrayList<>();
        for (int i = 0; i < maxWeek; i++) {
            weekList.add(i + 1);
        }
        schedule.setWeekList(weekList);
        setSchedule(schedule);
        return this;
    }

    /**
     * 设置查看课程详情时的课程数据
     *
     * @param schedules 课程数据
     * @return ClassDetailPopWindow
     */
    public ClassDetailPopWindow setScheduleList(List<Schedule> schedules) {
        List<Integer> weekList = new ArrayList<>();
        boolean isAdd = false;
        for (Schedule schedule : schedules) {
            if (!isAdd) {
                mSchedule = schedule;
                isAdd = true;
            }
            weekList.addAll(schedule.getWeekList());
        }
        mSchedule.setWeekList(weekList);
        reFreshUIState();
        return this;
    }

    public ClassDetailPopWindow setSchedule(Schedule schedule) {
        mSchedule = schedule;
        reFreshUIState();
        return this;
    }

    public Schedule getSchedule() {
        mWeekList.clear();
        mSchedule.setName(getTextString(mEtCourseName));
        mSchedule.setRoom(getTextString(mEtRoomName));
        mSchedule.setTeacher(getTextString(mEtTeacherName));
        for (WeekNumbers weekNumber : mWeekNumbers) {
            if (weekNumber.isSelected()) {
                mWeekList.add(weekNumber.getWeekNumber());
            }
        }
        mSchedule.setWeekList(mWeekList);
        return mSchedule;
    }

    private String getTextString(EditText editText) {
        return editText.getText().toString().trim();
    }

    public int getMaxWeek() {
        return maxWeek;
    }

    public ClassDetailPopWindow setMaxWeek(int maxWeek) {
        this.maxWeek = maxWeek;
        return this;
    }

    /**
     * 当数据发生改变的时候调用此方法刷新UI状态
     */
    public void reFreshUIState() {
        setCourseEnabled(mCourseEditBtn.isChecked());
        //课程名称
        if (mEtCourseName != null && mSchedule.getName() != null) {
            mEtCourseName.setText(mSchedule.getName());
            mEtCourseName.setFocusable(true);
            mEtCourseName.setSelection(mSchedule.getName().length());
        }
        //教室
        if (mEtRoomName != null && mSchedule.getRoom() != null) {
            mEtRoomName.setText(mSchedule.getRoom());
        }
        //教师姓名
        if (mEtTeacherName != null && mSchedule.getTeacher() != null) {
            mEtTeacherName.setText(mSchedule.getTeacher());
        }
        int step = mSchedule.getStep();
        //上课时间相关
        int startStep = mSchedule.getStart();
        int endStep = startStep + step -1;
        String[] festivalIntervalTime = MyScheduleSupport.getFestivalIntervalTime(startStep, endStep);
        mTvClassTime.setText(String.format("%s-%1s", festivalIntervalTime[0], festivalIntervalTime[1]));
        //上课节数
        mInputNumberView.setNumber(step);
        //设置为全选状态
        mRbSelectAll.setChecked(true);
        //先将所有选项置为未选中状态，再进行下一步操作
        resetAllWeekSelected();
        for (Integer integer : mSchedule.getWeekList()) {
            int week = integer - 1;
            if (mWeekNumbers.size() > week) {
                WeekNumbers weekNumbers = mWeekNumbers.get(week);
                weekNumbers.setSelected(true);
            }
        }
        //刷新周次选择列表
        notifyAdapterDataChanged();
    }

    @SuppressLint("NonConstantResourceId")
    private void initEvent() {
        mCourseEditBtn.setOnCheckedChangeListener((buttonView, isChecked) -> setCourseEnabled(isChecked));
        mRgWeekSelector.setOnCheckedChangeListener((group, checkedId) -> {
            resetAllWeekSelected();
            switch (checkedId) {
                case R.id.rbSingleWeek:
                    for (int i = 0; i < mWeekNumbers.size(); i++) {
                        WeekNumbers weekNumber = mWeekNumbers.get(i);
                        int currentPosition = i + 1;
                        weekNumber.setSelected(currentPosition % 2 == 1);
                    }
                    break;
                case R.id.rbDoubleWeek:
                    for (int i = 0; i < mWeekNumbers.size(); i++) {
                        WeekNumbers weekNumber = mWeekNumbers.get(i);
                        int currentPosition = i + 1;
                        weekNumber.setSelected(currentPosition % 2 == 0);
                    }
                    break;
                case R.id.rbSelectAll:
                    for (WeekNumbers weekNumber : mWeekNumbers) weekNumber.setSelected(true);
                    break;
            }
            mClassDetailAdapter.notifyDataSetChanged();
        });
        mBtnCancel.setOnClickListener(v -> dismiss());
        mBtnSubmit.setOnClickListener(v -> {
            //验证课程信息并提交之后再关闭PopWindow
            String courseName = mEtCourseName.getText().toString().trim();
            if (TextUtils.isEmpty(courseName)) {
                ToastUtils.showShort("课程名称不能为空！");
                return;
            }
            if (mOnSubmitListener != null) {
                mOnSubmitListener.onSubmit(mSchedule, mCourseEditBtn.isChecked());
            }
            dismiss();
        });
    }

    public void setCourseEnabled(boolean enabled) {
        mCourseEditBtn.setEnabled(enabled);
        mEtCourseName.setEnabled(enabled);
        mEtRoomName.setEnabled(enabled);
        mEtTeacherName.setEnabled(enabled);
        if (enabled) {
            mInputNumberView.setDisable(false).setUpButtonEnabled().setMinusEnabled();
        } else {
            mInputNumberView.setDisable(true).upButtonState();
        }
        mRbSingleWeek.setEnabled(enabled);
        mRbDoubleWeek.setEnabled(enabled);
        mRbSelectAll.setEnabled(enabled);
        if (enabled) {
            mClassDetailAdapter.setEnables();
        } else {
            mClassDetailAdapter.setDisEnables();
        }
    }

    public void setOnSubmitListener(OnSubmitListener onSubmitListener) {
        mOnSubmitListener = onSubmitListener;
    }

    private OnSubmitListener mOnSubmitListener;

    public interface OnSubmitListener {
        /**
         * 只有为启用状态才能保存数据
         *
         * @param schedule
         * @param enabled  是否启用
         */
        void onSubmit(Schedule schedule, boolean enabled);
    }

    private void resetAllWeekSelected() {
        for (WeekNumbers weekNumber : mWeekNumbers) {
            weekNumber.setSelected(false);
        }
    }
}
